package org.ztr.yanai.blog.controller;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.ztr.yanai.blog.utils.Result;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: ZhaoTR
 * @Date: Created in 2025/11/22 12:25
 * @Description: Nacos服务发现测试控制器
 * @Version: 1.0
 */
@RestController
@RequestMapping("/nacos")
@Tag(name = "Nacos测试", description = "Nacos服务注册与发现测试接口")
public class NacosTestController {

    private final DiscoveryClient discoveryClient;

    @Autowired(required = false)
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Autowired(required = false)
    private NamingService namingService;

    @Value("${spring.application.name}")
    private String applicationName;

    @Value("${server.port}")
    private String serverPort;

    @Value("${spring.cloud.nacos.discovery.server-addr:未配置}")
    private String nacosServerAddr;

    @Value("${spring.cloud.nacos.discovery.enabled:false}")
    private boolean discoveryEnabled;

    @Value("${spring.cloud.nacos.discovery.register-enabled:false}")
    private boolean registerEnabled;

    public NacosTestController(DiscoveryClient discoveryClient) {
        this.discoveryClient = discoveryClient;
    }

    @GetMapping("/info")
    @Operation(summary = "获取服务信息", description = "获取当前服务在Nacos中注册的信息")
    public Result<Map<String, Object>> getServiceInfo() {
        Map<String, Object> info = new HashMap<>();
        info.put("applicationName", applicationName);
        info.put("serverPort", serverPort);
        info.put("nacosEnabled", true);
        
        List<ServiceInstance> instances = discoveryClient.getInstances(applicationName);
        info.put("instanceCount", instances.size());
        info.put("instances", instances);
        
        return Result.success(info);
    }

    @GetMapping("/services")
    @Operation(summary = "获取所有服务", description = "获取Nacos中注册的所有服务列表")
    public Result<Map<String, Object>> getAllServices() {
        List<String> services = discoveryClient.getServices();
        Map<String, Object> result = new HashMap<>();
        result.put("serviceCount", services.size());
        result.put("services", services);
        return Result.success(result);
    }

    @GetMapping("/health")
    @Operation(summary = "健康检查", description = "检查服务是否正常运行")
    public Result<String> health() {
        return Result.success("服务正常运行，已注册到Nacos");
    }

    @GetMapping("/config")
    @Operation(summary = "获取Nacos配置", description = "获取当前应用的Nacos配置信息")
    public Result<Map<String, Object>> getNacosConfig() {
        Map<String, Object> config = new HashMap<>();
        config.put("nacosServerAddr", nacosServerAddr);
        config.put("discoveryEnabled", discoveryEnabled);
        config.put("registerEnabled", registerEnabled);
        config.put("applicationName", applicationName);
        config.put("serverPort", serverPort);
        
        if (nacosDiscoveryProperties != null) {
            config.put("namespace", nacosDiscoveryProperties.getNamespace());
            config.put("group", nacosDiscoveryProperties.getGroup());
            config.put("clusterName", nacosDiscoveryProperties.getClusterName());
            config.put("metadata", nacosDiscoveryProperties.getMetadata());
        }
        
        return Result.success(config);
    }

    @GetMapping("/service/{serviceName}")
    @Operation(summary = "获取指定服务实例", description = "获取指定服务名的所有实例详情")
    public Result<Map<String, Object>> getServiceInstances(@PathVariable String serviceName) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<ServiceInstance> instances = discoveryClient.getInstances(serviceName);
            result.put("serviceName", serviceName);
            result.put("instanceCount", instances.size());
            result.put("instances", instances.stream().map(instance -> {
                Map<String, Object> instanceInfo = new HashMap<>();
                instanceInfo.put("host", instance.getHost());
                instanceInfo.put("port", instance.getPort());
                instanceInfo.put("uri", instance.getUri());
                instanceInfo.put("metadata", instance.getMetadata());
                instanceInfo.put("instanceId", instance.getInstanceId());
                return instanceInfo;
            }).collect(Collectors.toList()));
        } catch (Exception e) {
            result.put("error", e.getMessage());
        }
        
        return Result.success(result);
    }

    @GetMapping("/naming/all")
    @Operation(summary = "通过NamingService获取所有服务", description = "直接调用Nacos NamingService API获取服务列表")
    public Result<Map<String, Object>> getAllServicesFromNaming() {
        Map<String, Object> result = new HashMap<>();
        
        if (namingService == null) {
            result.put("error", "NamingService未注入，请检查Nacos配置");
            return Result.success(result);
        }
        
        try {
            // 获取所有服务名称
            List<String> services = namingService.getServicesOfServer(1, 100).getData();
            result.put("serviceCount", services.size());
            result.put("services", services);
            
            // 获取每个服务的实例详情
            Map<String, List<Instance>> serviceInstances = new HashMap<>();
            for (String service : services) {
                List<Instance> instances = namingService.getAllInstances(service);
                serviceInstances.put(service, instances);
            }
            result.put("serviceDetails", serviceInstances);
            
        } catch (NacosException e) {
            result.put("error", "获取服务失败: " + e.getMessage());
            result.put("errorCode", e.getErrCode());
        }
        
        return Result.success(result);
    }

    @GetMapping("/register/status")
    @Operation(summary = "检查注册状态", description = "检查当前服务是否成功注册到Nacos")
    public Result<Map<String, Object>> checkRegisterStatus() {
        Map<String, Object> status = new HashMap<>();
        
        status.put("配置的服务名", applicationName);
        status.put("Nacos地址", nacosServerAddr);
        status.put("服务发现是否启用", discoveryEnabled);
        status.put("服务注册是否启用", registerEnabled);
        
        // 检查自己是否能被发现
        try {
            List<ServiceInstance> instances = discoveryClient.getInstances(applicationName);
            status.put("自身服务实例数", instances.size());
            status.put("注册状态", instances.isEmpty() ? "❌ 未注册" : "✅ 已注册");
            status.put("实例详情", instances);
        } catch (Exception e) {
            status.put("注册状态", "❌ 检查失败");
            status.put("错误信息", e.getMessage());
        }
        
        // 检查DiscoveryClient类型
        status.put("DiscoveryClient类型", discoveryClient.getClass().getName());
        
        return Result.success(status);
    }

    @GetMapping("/debug")
    @Operation(summary = "调试信息", description = "获取所有调试信息")
    public Result<Map<String, Object>> debugInfo() {
        Map<String, Object> debug = new HashMap<>();
        
        // 基本配置
        debug.put("应用名称", applicationName);
        debug.put("服务端口", serverPort);
        debug.put("Nacos地址", nacosServerAddr);
        debug.put("发现启用", discoveryEnabled);
        debug.put("注册启用", registerEnabled);
        
        // Bean注入状态
        debug.put("DiscoveryClient已注入", discoveryClient != null);
        debug.put("NacosDiscoveryProperties已注入", nacosDiscoveryProperties != null);
        debug.put("NamingService已注入", namingService != null);
        
        // 获取所有服务
        try {
            assert discoveryClient != null;
            List<String> services = discoveryClient.getServices();
            debug.put("发现的服务总数", services.size());
            debug.put("服务列表", services);
        } catch (Exception e) {
            debug.put("获取服务列表失败", e.getMessage());
        }
        
        return Result.success(debug);
    }
}
